--set each frame by BMAX:
mouseleft = 0
mousx = 0
mousy = 0
oldmousx = 0
oldmousy = 0
xres = 0
yres = 0
--
mouseleftdouble = false
mouseleftdoubletime = 0.0
dblstartx = 0
dblstarty = 0

numframes = 0
deltatime = 0
time = 0

player = {}

enemies = {}
particles = {}
shooters = {}
bullets = {}
line = {}
linelists = {}
collidedPoly = {}
collidedPolyIndex = nil
collidePoint = {}

tx = -100
ty = 0
scrollSpeedX = 120
scrollSpeedY = 0

drawingLine = false
gameMode = true

Line = {}
function Line.addPoint( point )
  table.insert(line, point)
end

function printf(fmt, ...)
  io.write(string.format(fmt, ...))
end

function setup()
  print('setup')
  math.randomseed( os.time() )
  dofile( "table.save-0.94.lua" )
  dofile( "particles.lua" )

  player.x = 0
  player.y = yres/2
  player.radius = 50
  player.alive = true

  -- Load level
  linelists = table.load( "test.tbl" )
end

function draw()
  time = time + deltatime

  -- Scroll level
  --
  --player.x = player.x + scrollSpeedX * deltatime

  setOrigin(-tx,-ty)
  mousx = mousx+tx
  mousy = mousy+ty

  if gameMode==true then
    tx = tx + scrollSpeedX * deltatime
    ty = 0--player.y - yres/2
  if player.alive then

    local vecToPlayer = {}
    vecToPlayer.x = mousx - player.x
    vecToPlayer.y = mousy - player.y
    normalize(vecToPlayer)

    player.x = tx+50--player.x + vecToPlayer.x * (scrollSpeedX*1.4) * deltatime
    --player.x = player.x + vecToPlayer.x * (scrollSpeedX*1.4) * deltatime
    player.y = player.y + vecToPlayer.y * (scrollSpeedX*1.4) * deltatime

    table.insert(particles,
    Particle.new( player.x + math.random(10) -5 - vecToPlayer.x*player.radius/2, player.y + math.random(10) -5 -vecToPlayer.y*player.radius/2  ))

    setcolor(0,0,255)
    drawsph(player.x,player.y,player.radius)
    setcolor(255,255,255)
    drawsph(player.x+5,player.y-5,15)
    setcolor(0,0,0)
    drawsph(player.x+5+vecToPlayer.x*3.5,player.y+vecToPlayer.y*3.5-5,5)
  else
    setcolor(255,0,255)
    drawsph(player.x,player.y,player.radius)
    setcolor(255,255,255)
    drawsph(player.x+5,player.y-5,20)
    setcolor(0,0,0)
    drawline(player.x+10+5,player.y-10-5,player.x-10+5,player.y+10-5)
    drawline(player.x+10+5,player.y+10-5,player.x-10+5,player.y-10-5)
  end

  --player.x = mousx
  --player.y = mousy

  setcolor(255,255,255)
  drawsph(mousx,mousy,10)

  dummyCircle = {}
  dummyCircle.x = player.x
  dummyCircle.y = player.y
  dummyCircle.radius = player.radius/2.0 - 3
  if circlePolylineIntersect(dummyCircle) then
    if player.alive then
      player.alive = false
      circleExplosion(player.x,player.y,player.radius)
      scrollSpeedX = 0
    end
  end


    if mouseLeftHit==1 and player.alive==false then
      tx = -50
      ty = 0
      scrollSpeedX = 120
      player.alive = true
      player.x = 0
      player.y = yres/2
    end
  end

  --[[
  if collidePoint.x ~= nil then
    setcolor(0,0,255)
    drawsph(collidePoint.x, collidePoint.y, 10)
  end
  ]]

  for k,v in pairs(linelists) do
      drawPolyline(v)
  end

  drawPolyline(line) -- Active, drawing line

  DrawParticles()


  if line[#line] ~= nil then
    setcolor(48,32,0)
    drawSparkler(line[#line].x, line[#line].y, 3 )
  end




  setOrigin(0,0)
  if mouseMiddleHit==1 or keyspacehit==1 then
    gameMode = not gameMode
  end
  if gameMode==false then
    Input()

    mousx = mousx-tx
    mousy = mousy-ty
    doGUI()
  end

  setcolor(255,255,255)
  --bmxprintf(10, 10, "numframes " .. numframes)
  bmxprintf(10, 20, "dt: " .. deltatime)
  --if collidedPoly~=nil then bmxprintf(10, 30, "collidedPoly exists" ) end
  bmxprintf(10, 40, "lines in active: " .. #line)
  bmxprintf(10, 50, "linelists: " .. #linelists)
  bmxprintf(10, 60, "particles: " .. #particles)

  if player.alive == false then
    bmxprintf(xres/2-50, yres/2, "Click mouse left to restart")
  end

  oldmousx = mousx
  oldmousy = mousy
  numframes = numframes + 1
end

function normalize(v)
  len = dist(v.x,v.y,0,0)
  v.x = v.x / len
  v.y = v.y / len
end


function Input()
  local mouseInEditArea = false
  if mousy-ty < (yres-30) then
    mouseInEditArea = true
  end

  if mouseLeftHit == 1 and mouseInEditArea then
    drawingLine = true
    local p1 = {}
    p1.x = mousx
    p1.y = mousy
    Line.addPoint(p1)
  end

  if mouseleftdouble and mouseInEditArea then
    drawingLine = false
    table.insert(linelists, line)
    line = {}
  end

  if drawingLine==false then
  local circle = {}
  circle.x = mousx
  circle.y = mousy
  circle.radius = 10
  circlePolylineIntersect(circle)
    if mouseRightHit == 1 and collidedPoly ~= nil then
      table.remove( linelists, collidedPolyIndex )
      collidedPoly = nil
      collidedPolyIndex = nil
    end
  end

  if( mouseLeftHit == 1 and mouseleftdouble==true ) then
    mouseleftdouble = false
  end

  if mouseleftdouble then
    mouseleftdouble = false
  end

  if( mouseLeftHit == 1 ) then
    if(mousx == dblstartx and mousy == dblstarty) then
      if( mouseleftdoubletime > time ) then
        mouseleftdouble = true
        print "dbl klik"
      end
    end
  end


  if( mouseLeftHit == 1 and mouseleftdouble==false ) then
    mouseleftdoubletime = time+0.3
    dblstartx = mousx
    dblstarty = mousy
  end
end

function doGUI()
  --Show gui border
  setcolor(128,128,128)
  drawline(0,yres-30, xres, yres-30)

  if button(xres-(45+5)*1, yres-25, 40, 20, "right") or keyright==1 then
    tx = tx + 500 * deltatime
  end
  if button(xres-(45+5)*2, yres-25, 40, 20, "left") or keyleft==1 then
    tx = tx - 500 * deltatime
  end
  if button(xres-(45+5)*3, yres-25, 40, 20, "up") or keyup==1 then
    ty = ty - 500 * deltatime
   end
  if button(xres-(45+5)*4, yres-25, 40, 20, "down") or keydown==1 then
    ty = ty + 500 * deltatime
  end

  if button(25+2*50+2*5, yres-25, 50, 20, "undo") then
    if mouseLeftHit==1 then table.remove( line, #line ) end
  end

  if button(25+3*50+3*5, yres-25, 50, 20, "save") then
    --// test save to file
    assert( table.save( linelists, "test.tbl" ) == 1 )
  end

  if button(25+4*50+4*5, yres-25, 50, 20, "load") then
    linelists = table.load( "test.tbl" )
  end
end


function button(x,y,w,h,text)
  setcolor(255,255,255)
  if isPointOverRect(mousx, mousy, x,y, w, h) then --check mouse collision with btn
    drawRect(x,y,w,h)
    if mouseleft==1 then setcolor(150,40,20) else setcolor(255,0,0) end
    fillRect(x+1,y+1,w-1,h-1)
    setcolor(255,255,255)
    bmxprintf(x+3, y+5, text)
    if mouseleft==1 then return true end
  else
    drawRect(x,y,w,h)
    bmxprintf(x+5, y+5, text)
  end
  return false
end

function drawPolyline(p)
  if p[1] == nil then return end

  if p == collidedPoly then
    setcolor(255,255,0)
  else
    setcolor(255,255,255)
  end

  local ox = p[1].x
  local oy = p[1].y
  for k,v in pairs(p) do
    if k==1 then
      --continue
    else
      x1 = v.x
      y1 = v.y
      drawline(ox,oy,x1,y1)
      ox=x1 oy = y1
    end

  end
end

--
function isPointOverRect(px,py,x,y,w,h)
   if(px >= x and px <= x+w) then
   if(py >= y and py <= y+h) then
      return true;
   end
   end
  return false;
end

function circleInRect(x,y,x0,y0,x1,y1,radi)
  if(x1 < x0) then
    t=x0
    x0=x1
    x1=t
  end
  if(y1 < y0) then
    t=y0
    y0=y1
    y1=t
  end
  if( (x+radi) > x0 and (x-radi) < x1 and (y+radi) > y0 and (y-radi) < y1) then
    return true
  end

  return false;
end

function distSq(x1,y1,x2,y2)
  return (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1)
end

function dist(x1,y1,x2,y2)
  local dx = math.abs(x2-x1)
  local dy = math.abs(y2-y1)
  if( dx < 0.0 and dy < 0.0 ) then return 0.0 end
  return math.sqrt( dx*dx + dy*dy )
end

function linePointDistance(px,py,x1,y1,x2,y2)
  local d = dist(x1,y1,x2,y2)
  if( d < 1e-7 ) then d = 1e-7 end
  return ( (x2-x1)*(y1-py) - (x1-px)*(y2-y1) ) / d;
end

function ldistfast(x,y,x0,y0,x1,y1)
  local dx=x1-x0
  local dy=y1-y0
  x1=x1+x0
  y1=y1+y0;
  local nx=x-x0
  local ny=y-y0;
  f=nx*dx+ny*dy  if(f<=0) then return(nx*ny+ny*ny) end
  g=dx*dx+dy*dy; if(f> g) then return( (x-x1)*(x-x1)+(y-y1)*(y-y1) ) end
  return( ( (nx*dy-ny*dx)*(nx*dy-ny*dx) ) /g);
end

function circleLineIsect(circle,line)
  if circleInRect(circle.x,circle.y,line.x0,line.y0,line.x1,line.y1,circle.radius) then
    local dist = math.abs( linePointDistance(circle.x,circle.y,line.x0,line.y0,line.x1,line.y1) )
    --local dist = ldistfast(circle.x,circle.y,line.x0,line.y0,line.x1,line.y1)
    if dist < circle.radius then
      collidePoint = circle
      --print(math.sqrt(dist))
      return true
    end
  end
end

function circlePolyCollide(point,p)
  if p[1] == nil then return end

  local ox = p[1].x
  local oy = p[1].y
  for k,v in pairs(p) do
    if k==1 then
      --continue
    else
      x1 = v.x
      y1 = v.y

      local linesegment = {}
      linesegment.x0 = ox
      linesegment.y0 = oy
      linesegment.x1 = x1
      linesegment.y1 = y1
      if circleLineIsect(point,linesegment) then
        return true
      end

      ox=x1 oy = y1
    end

  end

  return nil
end

function circlePolylineIntersect(c)
  for i,v in pairs(linelists) do
    if circlePolyCollide(c,v) then
      collidedPoly = v
      collidedPolyIndex = i
      return true
    end
  end
  collidedPoly = nil
end

